package cn.project.servlet;

import cn.project.util.MD5;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.*;

/**
 * 发送邮件至邮箱
 */
@WebServlet(name="register",urlPatterns = {"/register"}) //,loadOnStartup = 1
public class MailSenderServlet extends HttpServlet {

    private final static String PWD ="redis@WSX!QAZ1234XXX";
    private static Jedis redis =null;

    /**
     * 获取redis数据库连接
     */
    public MailSenderServlet(){
        System.out.println("==========MailSenderServlet");
        //实际上按面向对象的逻辑,此段应封装到Jredis的工具类中,
        //此处为了方便理解,暂不做封装

        //实例化连接池 ,JedisPool是一个线程安全的网络连接池
        JedisPoolConfig conf = new JedisPoolConfig();
        //设置连接池最大连接数和等待时常等参数
        //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
        conf.setMaxActive(20);
        //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
        conf.setMaxIdle(10);
        //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
        conf.setMaxWait(1000);
        //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
        conf.setTestOnBorrow(true);

        //获取jedis实例
        JedisPool pool = new JedisPool(conf,
                "127.0.0.1",6379,2000,PWD);
        redis = pool.getResource();
//        String uname = jedis.get("str");  测试连接用
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 收件人的电子邮件 ID
        String to = req.getParameter("email");
        String from = "*****@163.com";//如"jlj0130@163.com";
        //假设这一串就是生成的激活码
        //String activeCode = "ADSF65AASDFASFJLQWR86ASDFASFASF76ASF";
        //用Util中的MD5类根据系统时间生成唯一的32位激活码
        String activeCode = MD5.getMd5(new Date().toString(),32);
        try {
            sendMail(to, from, activeCode);
            //设置激活码到缓存服务器，有效期24小时（86400秒）
            //此处为15分钟 即 15*60s
            redis.setex(to, 15*60 ,activeCode);

            req.setAttribute("msg", "发送激活邮件到您的邮箱，15分钟内有效，请及时进入邮箱激活");

            RequestDispatcher rd = req.getRequestDispatcher("register-result.jsp");
            rd.forward(req,resp);
        }catch (GeneralSecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (AddressException e) {
            e.printStackTrace();
        }
    }
    private static void sendMail(String to,String from,String activeCode) throws FileNotFoundException, IOException, GeneralSecurityException, AddressException {
        //设置邮箱相关属性,也可设置在.properties文件中
        //此处为方便演示,直接配置成硬编码,
        //注意修改password的value
        Properties props = new Properties();
        props.put("username", from);
        props.put("password", "*****activeCode"); //------此处是你的邮箱对应的授权码,具体参考163邮箱开启用户激活码操作
        props.put("mail.transport.protocol", "smtp" );  //transport
        props.put("mail.smtp.host", "smtp.163.com");  //host
        props.put("mail.smtp.port", "25" );             //port

        //获取session
        Session mailSession = Session.getDefaultInstance(props);

        //显示在用户邮箱内的文字内容
        Message msg = new MimeMessage(mailSession);
        try {
            msg.setFrom(new InternetAddress(from));
            msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            msg.setContent("<h1>此邮件为官方激活邮件</h1>","text/html;charset=UTF-8");
            msg.setSubject("请激活您的账号");

            msg.setSentDate(new Date());
            msg.setContent(
                    "亲爱的用户xxx您好:<br/>&nbsp;&nbsp;&nbsp;&nbsp;"
                            + "请点击以下链接激活您的账号："
                            + "<a href=\"http://localhost:8888/authdemo/active?"
                            + "m="+to+"&c="+activeCode+"\">点击激活</a>该链接24小时内有效",
                    "text/html;charset=utf-8");
            msg.saveChanges();

            //发送邮件
            Transport transport = mailSession.getTransport("smtp");
            transport.connect(props.getProperty("mail.smtp.host"), props
                    .getProperty("username"), props.getProperty("password"));
            transport.sendMessage(msg, msg.getAllRecipients());
            //关闭transport
            transport.close();
        } catch (MessagingException e) {
            e.printStackTrace();
        }


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // super.doPost(req, resp);
        this.doGet(req, resp);

    }
}
